home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / nn.zip / KEYMAP.C < prev    next >
C/C++ Source or Header  |  1989-12-31  |  17KB  |  791 lines

  1. #include "config.h"
  2. #include "keymap.h"
  3. #include "term.h"
  4.  
  5.  
  6. /*
  7.  * standard keyboard mapping for more()
  8.  *
  9.  *    redraw            ^L, ^R
  10.  *    continue        space
  11.  *    repeat message        ^P
  12.  *    help            ?
  13.  *    shell escape        !
  14.  *    version            V
  15.  *    extended command    :
  16.  *    quit            Q
  17.  *
  18.  *    save            S, O
  19.  *    save, no header        W
  20.  *    reply            R
  21.  *    follow up        F
  22.  *    mail (forward)        M
  23.  *    cancel            C
  24.  *    unsubscribe        U
  25.  *    group overview        Y
  26.  *    print article        P
  27.  *    kill handling        K
  28.  *
  29.  *    update, goto next group    X
  30.  *    no update, next group    q, Z
  31.  *    return to menu        =
  32.  *    prev article        p    
  33.  *    goto group        G
  34.  *
  35.  *    line forward        CR/NL
  36.  *    half page forward    d/^D
  37.  *    half page back        u/^U
  38.  *    full page back        BS, DEL, (up arrow)
  39.  *    goto line        g
  40.  *    goto match        /
  41.  *    next match        .
  42.  *    
  43.  *    select subject        N, *
  44.  *
  45.  *    header            h
  46.  *    digest header        H
  47.  *    top            t
  48.  *    last page        $
  49.  *    leave article        l
  50.  *    next article        n
  51.  *    kill subject        k
  52.  *
  53.  *    rot13            D
  54.  *    compress        c
  55.  */
  56.  
  57. export int more_key_map[KEY_MAP_SIZE] = {
  58.  
  59. /* NUL ^@ */    K_UNBOUND, 
  60. /* SOH ^A */    K_UNBOUND, 
  61. /* STX ^B */    K_UNBOUND, 
  62. /* ETX ^C */    K_UNBOUND, 
  63. /* EOT ^D */        K_NEXT_HALF_PAGE, 
  64. /* ENQ ^E */    K_UNBOUND, 
  65. /* ACK ^F */    K_UNBOUND, 
  66. /* BEL ^G */        K_INVALID, 
  67. /* BS  ^H */        K_PREV_PAGE, 
  68. /* TAB ^I */        K_SKIP_LINES, 
  69. /* NL  ^J */        K_NEXT_LINE, 
  70. /* VT  ^K */    K_UNBOUND, 
  71. /* FF  ^L */        K_REDRAW, 
  72. /* CR  ^M */        K_NEXT_LINE, 
  73. /* SO  ^N */    K_UNBOUND, 
  74. /* SI  ^O */    K_UNBOUND, 
  75. /* DLE ^P */        K_LAST_MESSAGE, 
  76. /* DC1 ^Q */    K_UNBOUND, 
  77. /* DC2 ^R */        K_REDRAW, 
  78. /* DC3 ^S */    K_UNBOUND, 
  79. /* DC4 ^T */    K_UNBOUND, 
  80. /* NAK ^U */        K_PREV_HALF_PAGE, 
  81. /* SYN ^V */        K_NEXT_PAGE, 
  82. /* ETB ^W */    K_UNBOUND, 
  83. /* CAN ^X */    K_UNBOUND, 
  84. /* EM  ^Y */    K_UNBOUND, 
  85. /* SUB ^Z */    K_UNBOUND, 
  86. /* ESC ^[ */    K_UNBOUND, 
  87. /* FS  ^\ */    K_UNBOUND, 
  88. /* GS  ^] */    K_UNBOUND, 
  89. /* RS  ^^ */    K_UNBOUND, 
  90. /* US  ^_ */    K_UNBOUND, 
  91. /* SP  */        K_CONTINUE, 
  92. /* !   */        K_SHELL, 
  93. /* "   */    K_UNBOUND, 
  94. /* #   */    K_UNBOUND, 
  95. /* $   */        K_LAST_PAGE, 
  96. /* %   */        K_PREVIEW, 
  97. /* &   */    K_UNBOUND, 
  98. /* '   */    K_UNBOUND, 
  99. /* (   */    K_UNBOUND, 
  100. /* )   */    K_UNBOUND, 
  101. /* *   */        K_SELECT_SUBJECT, 
  102. /* +   */    K_UNBOUND, 
  103. /* ,   */    K_UNBOUND, 
  104. /* -   */    K_UNBOUND, 
  105. /* .   */        K_NEXT_MATCH, 
  106. /* /   */        K_GOTO_MATCH, 
  107. /* 0   */    K_UNBOUND, 
  108. /* 1   */    K_UNBOUND, 
  109. /* 2   */    K_UNBOUND, 
  110. /* 3   */    K_UNBOUND, 
  111. /* 4   */    K_UNBOUND, 
  112. /* 5   */    K_UNBOUND, 
  113. /* 6   */    K_UNBOUND, 
  114. /* 7   */    K_UNBOUND, 
  115. /* 8   */    K_UNBOUND, 
  116. /* 9   */    K_UNBOUND, 
  117. /* :   */         K_EXTENDED_CMD, 
  118. /* ;   */    K_UNBOUND, 
  119. /* <   */    K_UNBOUND, 
  120. /* =   */        K_BACK_TO_MENU, 
  121. /* >   */    K_UNBOUND, 
  122. /* ?   */        K_HELP, 
  123. /* @   */    K_UNBOUND, 
  124. /* A   */    K_UNBOUND, 
  125. /* B   */    K_UNBOUND, 
  126. /* C   */        K_CANCEL, 
  127. /* D   */        K_ROT13, 
  128. /* E   */    K_UNBOUND, 
  129. /* F   */        K_FOLLOW_UP,
  130. /* G   */        K_GOTO_GROUP, 
  131. /* H   */        K_FULL_DIGEST,
  132. /* I   */    K_UNBOUND, 
  133. /* J   */    K_UNBOUND, 
  134. /* K   */        K_KILL_HANDLING,
  135. /* L   */    K_UNBOUND, 
  136. /* M   */        K_MAIL_OR_FORWARD, 
  137. /* N   */        K_NEXT_GROUP_NO_UPDATE, 
  138. /* O   */        K_SAVE_SHORT_HEADER, 
  139. /* P   */        K_PRINT, 
  140. /* Q   */         K_QUIT, 
  141. /* R   */        K_REPLY, 
  142. /* S   */        K_SAVE_FULL_HEADER, 
  143. /* T   */    K_UNBOUND, 
  144. /* U   */        K_UNSUBSCRIBE, 
  145. /* V   */         K_VERSION, 
  146. /* W   */        K_SAVE_NO_HEADER, 
  147. /* X   */        K_READ_GROUP_UPDATE, 
  148. /* Y   */        K_GROUP_OVERVIEW, 
  149. /* Z   */        K_BACK_TO_MENU, 
  150. /* [   */    K_UNBOUND, 
  151. /* \   */    K_UNBOUND, 
  152. /* ]   */    K_UNBOUND, 
  153. /* ^   */        K_FIRST_PAGE, 
  154. /* _   */    K_UNBOUND, 
  155. /* `   */    K_UNBOUND, 
  156. /* a   */        K_FORW_ARTICLE, 
  157. /* b   */        K_BACK_ARTICLE, 
  158. /* c   */        K_COMPRESS, 
  159. /* d   */        K_NEXT_HALF_PAGE, 
  160. /* e   */    K_UNBOUND, 
  161. /* f   */        K_FOLLOW_UP, 
  162. /* g   */        K_GOTO_LINE, 
  163. /* h   */        K_HEADER_PAGE, 
  164. /* i   */    K_UNBOUND, 
  165. /* j   */    K_UNBOUND, 
  166. /* k   */        K_NEXT_SUBJECT, 
  167. /* l   */        K_LEAVE_ARTICLE, 
  168. /* m   */        K_MAIL_OR_FORWARD, 
  169. /* n   */        K_NEXT_ARTICLE,
  170. /* o   */        K_SAVE_SHORT_HEADER, 
  171. /* p   */        K_PREVIOUS /* article */, 
  172. /* q   */        K_NEXT_GROUP_NO_UPDATE,
  173. /* r   */        K_REPLY,
  174. /* s   */        K_SAVE_FULL_HEADER, 
  175. /* t   */        K_FIRST_PAGE,
  176. /* u   */        K_PREV_HALF_PAGE,
  177. /* v   */    K_UNBOUND, 
  178. /* w   */        K_SAVE_NO_HEADER,
  179. /* x   */    K_UNBOUND, 
  180. /* y   */    K_UNBOUND, 
  181. /* z   */    K_UNBOUND, 
  182. /* {   */    K_UNBOUND, 
  183. /* |   */    K_UNBOUND, 
  184. /* }   */    K_UNBOUND, 
  185. /* ~   */    K_UNBOUND, 
  186. /* DEL */        K_PREV_PAGE,
  187. /* 200 */    K_UNBOUND, 
  188. /* up  */        K_PREV_PAGE,
  189. /* down */        K_NEXT_PAGE,
  190. /* left */    K_UNBOUND,
  191. /* right */    K_UNBOUND,
  192. /* #0  */    K_UNBOUND,
  193. /* #1  */    K_UNBOUND,
  194. /* #2  */    K_UNBOUND,
  195. /* #3  */    K_UNBOUND,
  196. /* #4  */    K_UNBOUND,
  197. /* #5  */    K_UNBOUND,
  198. /* #6  */    K_UNBOUND,
  199. /* #7  */    K_UNBOUND,
  200. /* #8  */    K_UNBOUND,
  201. /* #9  */    K_UNBOUND
  202. };
  203.  
  204.  
  205.  
  206. /*
  207.  * standard keyboard mappings for menu()
  208.  *
  209.  *    illegal command
  210.  *    redraw            ^L, ^R
  211.  *    continue        space
  212.  *    repeat message        ^P
  213.  *    help            ?
  214.  *    shell escape        !
  215.  *    version            V
  216.  *    alternative commands    :
  217.  *    quit            Q
  218.  *
  219.  *    save            S, O
  220.  *    save, no header        W
  221.  *    reply            R
  222.  *    follow up        F
  223.  *    mail (forward)        M
  224.  *    cancel            C
  225.  *    unsubscribe        U
  226.  *    group overview        Y
  227.  *    kill handling        K
  228.  *
  229.  *    read, then next        X
  230.  *    read, then same        Z
  231.  *    no update, next        N
  232.  *    prev group        P
  233.  *    goto group        G
  234.  *    advance group        A
  235.  *    back group        B
  236.  *
  237.  *    article identifier    a-z 0-9
  238.  *    inverse            @
  239.  *    select current, next    .
  240.  *    next            , (down arrow)
  241.  *    prev            / (up arrow)
  242.  *    select subject        *
  243.  *    range            -
  244.  *    auto select         +
  245.  *
  246.  *    next page        >
  247.  *    prev page        <
  248.  *    first page        ^
  249.  *    last page        $
  250.  *    
  251.  *    pre-view article    %
  252.  *
  253.  *    layout            L
  254.  */
  255.  
  256.  
  257. export int menu_key_map[KEY_MAP_SIZE] = {
  258.  
  259. /* NUL ^@ */    K_UNBOUND, 
  260. /* SOH ^A */    K_UNBOUND, 
  261. /* STX ^B */    K_UNBOUND, 
  262. /* ETX ^C */    K_UNBOUND, 
  263. /* EOT ^D */    K_UNBOUND, 
  264. /* ENQ ^E */    K_UNBOUND, 
  265. /* ACK ^F */    K_UNBOUND, 
  266. /* BEL ^G */        K_INVALID, 
  267. /* BS  ^H */        K_PREV_LINE,
  268. /* TAB ^I */    K_UNBOUND, 
  269. /* NL  ^J */        K_CONTINUE,
  270. /* VT  ^K */    K_UNBOUND, 
  271. /* FF  ^L */        K_REDRAW,
  272. /* CR  ^M */        K_CONTINUE,
  273. /* SO  ^N */    K_UNBOUND, 
  274. /* SI  ^O */    K_UNBOUND, 
  275. /* DLE ^P */        K_LAST_MESSAGE,
  276. /* DC1 ^Q */    K_UNBOUND, 
  277. /* DC2 ^R */        K_REDRAW,
  278. /* DC3 ^S */    K_UNBOUND, 
  279. /* DC4 ^T */    K_UNBOUND, 
  280. /* NAK ^U */    K_UNBOUND, 
  281. /* SYN ^V */    K_UNBOUND, 
  282. /* ETB ^W */    K_UNBOUND, 
  283. /* CAN ^X */    K_UNBOUND, 
  284. /* EM  ^Y */    K_UNBOUND, 
  285. /* SUB ^Z */    K_UNBOUND, 
  286. /* ESC ^[ */    K_UNBOUND, 
  287. /* FS  ^\ */    K_UNBOUND, 
  288. /* GS  ^] */    K_UNBOUND, 
  289. /* RS  ^^ */    K_UNBOUND, 
  290. /* US  ^_ */    K_UNBOUND, 
  291. /* SP  */        K_CONTINUE,
  292. /* !   */        K_SHELL,
  293. /* "   */    K_UNBOUND, 
  294. /* #   */    K_UNBOUND, 
  295. /* $   */        K_LAST_PAGE,
  296. /* %   */        K_PREVIEW,
  297. /* &   */    K_UNBOUND, 
  298. /* '   */    K_UNBOUND, 
  299. /* (   */    K_UNBOUND, 
  300. /* )   */    K_UNBOUND, 
  301. /* *   */        K_SELECT_SUBJECT,
  302. /* +   */        K_AUTO_SELECT,
  303. /* ,   */        K_NEXT_LINE,
  304. /* -   */        K_SELECT_RANGE,
  305. /* .   */        K_SELECT,
  306. /* /   */        K_PREV_LINE,
  307. /* 0   */    K_ARTICLE_ID + 26, 
  308. /* 1   */    K_ARTICLE_ID + 27, 
  309. /* 2   */    K_ARTICLE_ID + 28, 
  310. /* 3   */    K_ARTICLE_ID + 29, 
  311. /* 4   */    K_ARTICLE_ID + 30, 
  312. /* 5   */    K_ARTICLE_ID + 31, 
  313. /* 6   */    K_ARTICLE_ID + 32, 
  314. /* 7   */    K_ARTICLE_ID + 33, 
  315. /* 8   */    K_ARTICLE_ID + 34, 
  316. /* 9   */    K_ARTICLE_ID + 35, 
  317. /* :   */        K_EXTENDED_CMD,
  318. /* ;   */    K_UNBOUND, 
  319. /* <   */        K_PREV_PAGE,
  320. /* =   */        K_GOTO_MATCH, 
  321. /* >   */        K_NEXT_PAGE,
  322. /* ?   */        K_HELP,
  323. /* @   */        K_SELECT_INVERT,
  324. /* A   */        K_ADVANCE_GROUP,
  325. /* B   */        K_BACK_GROUP,
  326. /* C   */        K_CANCEL,
  327. /* D   */    K_UNBOUND, 
  328. /* E   */    K_UNBOUND, 
  329. /* F   */        K_FOLLOW_UP,
  330. /* G   */        K_GOTO_GROUP,
  331. /* H   */    K_UNBOUND, 
  332. /* I   */    K_UNBOUND, 
  333. /* J   */    K_UNBOUND, 
  334. /* K   */        K_KILL_HANDLING,
  335. /* L   */        K_LAYOUT,
  336. /* M   */        K_MAIL_OR_FORWARD,
  337. /* N   */        K_NEXT_GROUP_NO_UPDATE,
  338. /* O   */        K_SAVE_SHORT_HEADER,
  339. /* P   */        K_PREVIOUS /* group */,
  340. /* Q   */        K_QUIT,
  341. /* R   */        K_REPLY,
  342. /* S   */        K_SAVE_FULL_HEADER,
  343. /* T   */    K_UNBOUND, 
  344. /* U   */        K_UNSUBSCRIBE,
  345. /* V   */        K_VERSION,
  346. /* W   */        K_SAVE_NO_HEADER,
  347. /* X   */        K_READ_GROUP_UPDATE,
  348. /* Y   */        K_GROUP_OVERVIEW,
  349. /* Z   */        K_READ_GROUP_THEN_SAME,
  350. /* [   */    K_UNBOUND, 
  351. /* \   */    K_UNBOUND, 
  352. /* ]   */    K_UNBOUND, 
  353. /* ^   */        K_FIRST_PAGE,
  354. /* _   */    K_UNBOUND, 
  355. /* `   */    K_UNBOUND, 
  356. /* a   */    K_ARTICLE_ID +  0, 
  357. /* b   */    K_ARTICLE_ID +  1, 
  358. /* c   */    K_ARTICLE_ID +  2, 
  359. /* d   */    K_ARTICLE_ID +  3, 
  360. /* e   */    K_ARTICLE_ID +  4, 
  361. /* f   */    K_ARTICLE_ID +  5, 
  362. /* g   */    K_ARTICLE_ID +  6, 
  363. /* h   */    K_ARTICLE_ID +  7, 
  364. /* i   */    K_ARTICLE_ID +  8, 
  365. /* j   */    K_ARTICLE_ID +  9, 
  366. /* k   */    K_ARTICLE_ID + 10, 
  367. /* l   */    K_ARTICLE_ID + 11, 
  368. /* m   */    K_ARTICLE_ID + 12, 
  369. /* n   */    K_ARTICLE_ID + 13, 
  370. /* o   */    K_ARTICLE_ID + 14, 
  371. /* p   */    K_ARTICLE_ID + 15, 
  372. /* q   */    K_ARTICLE_ID + 16, 
  373. /* r   */    K_ARTICLE_ID + 17, 
  374. /* s   */    K_ARTICLE_ID + 18, 
  375. /* t   */    K_ARTICLE_ID + 19, 
  376. /* u   */    K_ARTICLE_ID + 20, 
  377. /* v   */    K_ARTICLE_ID + 21, 
  378. /* w   */    K_ARTICLE_ID + 22, 
  379. /* x   */    K_ARTICLE_ID + 23, 
  380. /* y   */    K_ARTICLE_ID + 24, 
  381. /* z   */    K_ARTICLE_ID + 25, 
  382. /* {   */    K_UNBOUND, 
  383. /* |   */    K_UNBOUND, 
  384. /* }   */    K_UNBOUND, 
  385. /* ~   */        K_UNSELECT_ALL, 
  386. /* DEL */        K_PREV_LINE,
  387. /* 200 */    K_UNBOUND, 
  388. /* up  */        K_PREV_LINE,
  389. /* down */        K_NEXT_LINE,
  390. /* left */    K_UNBOUND,
  391. /* right */    K_UNBOUND,
  392. /* #0  */    K_UNBOUND,
  393. /* #1  */    K_UNBOUND,
  394. /* #2  */    K_UNBOUND,
  395. /* #3  */    K_UNBOUND,
  396. /* #4  */    K_UNBOUND,
  397. /* #5  */    K_UNBOUND,
  398. /* #6  */    K_UNBOUND,
  399. /* #7  */    K_UNBOUND,
  400. /* #8  */    K_UNBOUND,
  401. /* #9  */    K_UNBOUND
  402. };
  403.  
  404.  
  405.  
  406. static struct command_name_map {
  407.     char *    cmd_name;
  408.     int       cmd_code;
  409.     int          cmd_restriction;
  410. } command_name_map[] = {
  411.     
  412.     "advance-article",        K_FORW_ARTICLE,        K_ONLY_MORE,
  413.     "advance-group",        K_ADVANCE_GROUP,    0,
  414.     "article",            K_ARTICLE_ID,        K_ONLY_MENU,
  415.     "as",            K_EQUAL_KEY,        0,
  416.  
  417.     "back-article",        K_BACK_ARTICLE,        K_ONLY_MORE,
  418.     "back-group",        K_BACK_GROUP,        0,
  419.  
  420.     "cancel",            K_CANCEL,        0,
  421.     "command",            K_EXTENDED_CMD,        0,
  422.     "compress",            K_COMPRESS,        K_ONLY_MORE,
  423.     "continue",            K_CONTINUE,        0,
  424.  
  425.     "decode",            K_UUDECODE,        0,
  426.  
  427.     "find",            K_GOTO_MATCH,        0,
  428.     "find-next",        K_NEXT_MATCH,        K_ONLY_MORE,
  429.     "follow",            K_FOLLOW_UP,        0,
  430.     "full-digest",        K_FULL_DIGEST,        K_ONLY_MORE,
  431.  
  432.     "goto-group",        K_GOTO_GROUP,        0,
  433.     "goto-menu",        K_BACK_TO_MENU,        K_ONLY_MORE,
  434.  
  435.     "help",            K_HELP,            0,
  436.  
  437.     "kill-select",        K_KILL_HANDLING,    0,
  438.  
  439.     "layout",            K_LAYOUT,        K_ONLY_MENU,
  440.     "leave-article",        K_LEAVE_ARTICLE,    K_ONLY_MORE,
  441.     "line+1",            K_NEXT_LINE,        0,
  442.     "line-1",            K_PREV_LINE,        0,
  443.     "line=@",            K_GOTO_LINE,        K_ONLY_MORE,
  444.  
  445.     "macro",            K_MACRO,        0,
  446.     "mail",            K_MAIL_OR_FORWARD,    0,
  447.     "message",            K_LAST_MESSAGE,        0,
  448.  
  449.     "next-article",        K_NEXT_ARTICLE,        K_ONLY_MORE,
  450.     "next-group",        K_NEXT_GROUP_NO_UPDATE,    0,
  451.     "next-subject",        K_NEXT_SUBJECT,        K_ONLY_MORE,
  452.     "nil",            K_UNBOUND,        0,
  453.  
  454.     "overview",            K_GROUP_OVERVIEW,    0,
  455.  
  456.     "page+1",            K_NEXT_PAGE,        0,
  457.     "page+1/2",            K_NEXT_HALF_PAGE,    K_ONLY_MORE,
  458.     "page-1",            K_PREV_PAGE,        0,
  459.     "page-1/2",            K_PREV_HALF_PAGE,    K_ONLY_MORE,
  460.     "page=$",            K_LAST_PAGE,        0,
  461.     "page=0",            K_HEADER_PAGE,        0,
  462.     "page=1",            K_FIRST_PAGE,        0,
  463.     "page=@",            K_GOTO_PAGE,        K_ONLY_MORE,
  464.  
  465.     "patch",            K_PATCH,        0,
  466.     "post",            K_POST,            0,
  467.     "preview",            K_PREVIEW,        0,
  468.     "previous",            K_PREVIOUS,        0,
  469.     "print",            K_PRINT,        0,
  470.  
  471.     "quit",            K_QUIT,            0,
  472.  
  473.     "read-return",        K_READ_GROUP_THEN_SAME,    K_ONLY_MENU,
  474.     "read-skip",        K_READ_GROUP_UPDATE,    0,
  475.     "redraw",            K_REDRAW,        0,
  476.     "reply",            K_REPLY,        0,
  477.     "rot13",            K_ROT13,        K_ONLY_MORE,
  478.  
  479.     "save-body",        K_SAVE_NO_HEADER,    0,
  480.     "save-full",        K_SAVE_FULL_HEADER,    0,
  481.     "save-short",        K_SAVE_SHORT_HEADER,    0,
  482.     "select",            K_SELECT,        K_ONLY_MENU,
  483.     "select-auto",        K_AUTO_SELECT,        K_ONLY_MENU,
  484.     "select-invert",        K_SELECT_INVERT,    K_ONLY_MENU,
  485.     "select-range",        K_SELECT_RANGE,        K_ONLY_MENU,
  486.     "select-subject",        K_SELECT_SUBJECT,    0,
  487.     "shell",            K_SHELL,        0,
  488.     "skip-lines",        K_SKIP_LINES,        0,
  489.  
  490.     "unselect-all",        K_UNSELECT_ALL,        K_ONLY_MENU,
  491.     "unshar",            K_UNSHAR,        0,
  492.     "unsub",            K_UNSUBSCRIBE,        0,
  493.  
  494.     "version",            K_VERSION,        0,
  495.  
  496.     (char *)NULL,        0,            0
  497. };
  498.  
  499. static int name_map_size;
  500. static int max_cmd_name_length = 14;    /* recalculate if table is changed */
  501.  
  502. export unsigned char global_key_map[KEY_MAP_SIZE];
  503.  
  504.  
  505. init_key_map()
  506. {
  507.     register int c;
  508.     register struct command_name_map *cnmp;
  509.     
  510.     for (c = 0; c < KEY_MAP_SIZE; c++) global_key_map[c] = c;
  511.  
  512.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++);
  513.     name_map_size = cnmp - command_name_map;
  514. }
  515.  
  516.  
  517. lookup_command(command, restriction)
  518. char *command;
  519. int restriction;
  520. {
  521.     register struct command_name_map *cnmp;
  522.     register i, j, k, t;
  523.     
  524.     i = 0; j = name_map_size - 1; 
  525.     
  526.     while (i <= j) {
  527.     k = (i + j) / 2;
  528.     cnmp = &command_name_map[k];
  529.     
  530.     if ( (t=strcmp(command, cnmp->cmd_name)) > 0) 
  531.         i = k+1;
  532.     else
  533.     if (t < 0)
  534.         j = k-1;
  535.     else {
  536.         if (cnmp->cmd_restriction == 0
  537.         || (cnmp->cmd_restriction & restriction))
  538.         return cnmp->cmd_code;
  539.         break;
  540.     }
  541.     }
  542.  
  543.     return K_INVALID;
  544. }    
  545.  
  546.  
  547. cmd_completion(path, index)
  548. char *path;
  549. int index;
  550. {
  551.     static char *head, *tail = NULL;
  552.     static int len;
  553.     static struct command_name_map *cmd, *help_cmd;
  554.  
  555.     if (index < 0) return 0;
  556.  
  557.     if (path) {
  558.     head = path;
  559.     tail = path + index;
  560.     while (*head && isspace(*head)) head++;
  561.     help_cmd = cmd = command_name_map;
  562.     len = tail - head;
  563.     
  564.     return 1;
  565.     }
  566.     
  567.     if (index) {
  568.     list_completion((char *)NULL);
  569.  
  570.     if (help_cmd->cmd_name == NULL)
  571.         help_cmd = command_name_map;
  572.     
  573.     for (;help_cmd->cmd_name; help_cmd++) {
  574.         index = strncmp(help_cmd->cmd_name, head, len);
  575.         if (index < 0) continue;
  576.         if (index > 0) {
  577.         help_cmd = command_name_map;
  578.         break;
  579.         }
  580.         if (list_completion(help_cmd->cmd_name) == 0) break;
  581.     }
  582.     fl;
  583.     return 1;
  584.     }
  585.  
  586.     for (; cmd->cmd_name; cmd++) {
  587.     if (len == 0) 
  588.         index = 0;
  589.     else
  590.         index = strncmp(cmd->cmd_name, head, len);
  591.     if (index < 0) continue;
  592.     if (index > 0) break;
  593.     if (cmd->cmd_code == K_MACRO || 
  594.         cmd->cmd_code == K_ARTICLE_ID ||
  595.         cmd->cmd_code == K_EQUAL_KEY)
  596.         sprintf(tail, "%s ", cmd->cmd_name + len);
  597.     else
  598.         strcpy(tail, cmd->cmd_name + len);
  599.     cmd++;
  600.     return 1;
  601.     }
  602.     return 0;
  603. }
  604.  
  605.  
  606. char *command_name(cmd)
  607. int cmd;
  608. {
  609.     register struct command_name_map *cnmp;
  610.  
  611.     cmd &= ~GETC_COMMAND;
  612.  
  613.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++)
  614.     if (cnmp->cmd_code == cmd) return cnmp->cmd_name;
  615.     
  616.     return "unknown";
  617. }
  618.  
  619.  
  620. /*
  621.  * convert key name into ascii code
  622.  *
  623.  *    key names are:
  624.  *        c    character c
  625.  *        ^C    control-C
  626.  *        0xNN    hex value (0..0x7f)
  627.  *        0NNN    octal value (0..0177)
  628.  *        NNN    decimal value (0..127)
  629.  *        up, down, left, rigth    arrow keys
  630.  *        #0..#9            function keys (initially undefined)
  631.  */
  632.  
  633. parse_key(str)
  634. char *str;
  635. {
  636.     int x;
  637.     
  638.     if (str[1] == NUL)
  639.     return str[0] & 0177;
  640.     
  641.     if (str[0] == '^')
  642.     if (str[1] == '?') 
  643.         return 0177;
  644.     else
  645.         return CONTROL_(str[1]);
  646.     
  647.     if (isdigit(str[0])) {
  648.     if (str[0] == '0')
  649.         if (str[1] == 'x')
  650.         sscanf(str+2, "%x", &x);
  651.         else
  652.         sscanf(str+1, "%o", &x);
  653.     else
  654.         sscanf(str, "%d", &x);
  655.     
  656.     return x & 0177;
  657.     }
  658.  
  659.     if (str[0] == '#' && isdigit(str[1])) 
  660.     return K_function(str[1] - '0');
  661.     
  662.     if (strcmp(str, "up") == 0)
  663.     return K_up_arrow;
  664.     
  665.     if (strcmp(str, "down") == 0)
  666.     return K_down_arrow;
  667.     
  668.     if (strcmp(str, "left") == 0)
  669.     return K_left_arrow;
  670.     
  671.     if (strcmp(str, "right") == 0)
  672.     return K_right_arrow;
  673.  
  674.     init_message("unknown key: %s", str);
  675.     
  676.     return 0200;
  677. }
  678.  
  679. char *key_name(c)
  680. int c;
  681. {
  682.     static char buf[3];
  683.     
  684.     if (c & 0200) {
  685.     switch (c) {
  686.      case K_up_arrow:
  687.         return "up";
  688.      case K_down_arrow:
  689.         return "down";
  690.      case K_left_arrow:
  691.         return "left";
  692.      case K_right_arrow:
  693.         return "right";
  694.      default:
  695.         buf[0] = '#';
  696.         buf[1] = (c - K_function(0)) + '0';
  697.         buf[2] = NUL;
  698.         goto out;
  699.     }
  700.     }
  701.  
  702.     if (c < SP) {
  703.     buf[0] = '^';
  704.     buf[1] = c + '@';
  705.     buf[2] = NUL;
  706.     goto out;
  707.     }
  708.  
  709.     if (c == 0177) {
  710.     strcpy(buf, "^?");
  711.     goto out;
  712.     }
  713.  
  714.     buf[0] = c;
  715.     buf[1] = NUL;
  716.  
  717.  out:    
  718.     return buf;
  719. }
  720.  
  721.     
  722. dump_global_map()
  723. {
  724.     register int c;
  725.     
  726.     clrdisp();
  727.     so_printf("\1REMAPPED KEYS\1\n\n");
  728.     pg_init(2, 4);
  729.     
  730.     for (c = 0; c < KEY_MAP_SIZE; c++)
  731.     if (c != global_key_map[c]) {
  732.         if (pg_next() < 0) break;
  733.         printf("%s", key_name(c));
  734.         pg_indent(6);
  735.         printf("-> %s", key_name(global_key_map[c]));
  736.     }
  737.  
  738.     pg_end();
  739. }
  740.  
  741.  
  742. dump_key_map(map, where, restriction)
  743. int map[];
  744. char *where;
  745. int restriction;
  746. {
  747.     register struct command_name_map *cnmp;
  748.     register c, code, first_prt;
  749.     
  750.     clrdisp();
  751.     so_printf("\1KEY BINDINGS (%s)\1\n\n", where);
  752.  
  753.     if (restriction == K_ONLY_MENU) {
  754.     printf("\rarticle:  ");
  755.     for (c = 0; c < KEY_MAP_SIZE; c++)
  756.         if (map[c] & K_ARTICLE_ID) printf("%s", key_name(c));
  757.     }
  758.  
  759.     pg_init(4, 2);
  760.     
  761.     for (cnmp = command_name_map; cnmp->cmd_name; cnmp++) {
  762.     if (cnmp->cmd_restriction && cnmp->cmd_restriction != restriction)
  763.         continue;
  764.     if (cnmp->cmd_code == K_UNBOUND) continue;
  765.     if (cnmp->cmd_code == K_MACRO) continue;
  766.  
  767.     code = cnmp->cmd_code;
  768.     first_prt = 1;
  769.  
  770.     for (c = 0; c < KEY_MAP_SIZE; c++)
  771.         if (map[c] == code) {
  772.         if (first_prt) {
  773.             if (pg_next() < 0) goto out;
  774.             fputs(cnmp->cmd_name, stdout);
  775.             pg_indent(max_cmd_name_length);
  776.             first_prt = 0;
  777.         }
  778.         printf(" %s", key_name(c));
  779.         }
  780.     }
  781.  
  782.     for (c = 0; c < KEY_MAP_SIZE; c++)
  783.     if (map[c] & K_MACRO) {
  784.         if (pg_next() < 0) goto out;
  785.         printf("macro %d: %s", (map[c] & ~K_MACRO), key_name(c));
  786.     }
  787.  
  788.  out:
  789.     pg_end();
  790. }
  791.